﻿using System.Diagnostics;
using FRRJIf;

namespace RJi.FanucInterface3.Common.Internal;

internal class FanucRbt(
    Core core,
    string hostname,
    string name,
    Dictionary<string, VariableMetadata> primaryTableMetadataCache,
    Dictionary<string, VariableMetadata> secondTableMetadataCache,
    Dictionary<string, VariableMetadata> inputMetadataCache,
    Dictionary<string, VariableMetadata> outMetadataCache) : IFanucRbt
{
    private readonly Reader _reader = new(core, primaryTableMetadataCache, secondTableMetadataCache, inputMetadataCache, outMetadataCache);
    private readonly Stopwatch _refreshStopwatch1 = new();
    private readonly Stopwatch _refreshStopwatch2 = new();
    private readonly Stopwatch _refreshStopwatch3 = new();
    private readonly Stopwatch _refreshStopwatch4 = new();
    private readonly Writer _writer = new(); //todo:写服务没做，先不做，容易撞机

    public string Hostname
    {
        get { return hostname; }
    }

    public bool IsConnected { get; private set; }

    public string Name
    {
        get { return name; }
    }

    public IReader Reader
    {
        get { return _reader; }
    }

    public double RefreshInputTime { get; private set; }
    public double RefreshOutputTime { get; private set; }
    public double RefreshPrimaryTableTime { get; private set; }
    public double RefreshSecondTableTime { get; private set; }

    public IWriter Writer
    {
        get { return _writer; }
    }

    public void Connect()
    {
        IsConnected=core.Connect(Hostname);
        if (!IsConnected) throw new Exception($"Failed to connect to robot {Name} at {Hostname}");
    }

    public void Disconnect()
    {
        core.Disconnect();
    }

    public void RefreshInput()
    {
        if (!IsConnected) throw new Exception($"Failed to connect to robot {Name} at {Hostname}");
        _refreshStopwatch3.Start();
        _reader.UpdateInputVariables();
        _refreshStopwatch3.Stop();
        RefreshInputTime=_refreshStopwatch3.Elapsed.TotalMilliseconds;
        _refreshStopwatch3.Reset();
    }

    public void RefreshOutput()
    {
        if (!IsConnected) throw new Exception($"Failed to connect to robot {Name} at {Hostname}");
        _refreshStopwatch4.Start();
        _reader.UpdateOutputVariables();
        _refreshStopwatch4.Stop();
        RefreshOutputTime=_refreshStopwatch4.Elapsed.TotalMilliseconds;
        _refreshStopwatch4.Reset();
    }

    public void RefreshPrimaryTable()
    {
        if (!IsConnected) throw new Exception($"Failed to connect to robot {Name} at {Hostname}");
        _refreshStopwatch1.Start();
        var result = core.DataTable.Refresh();
        _refreshStopwatch1.Stop();
        if (!result) throw new Exception($"Failed to refresh to robot {Name} at {Hostname}");
        _reader.UpdatePrimaryTableVariables();
        RefreshPrimaryTableTime=_refreshStopwatch1.Elapsed.TotalMilliseconds;
        _refreshStopwatch1.Reset();
    }

    public void RefreshSecondaryTable()
    {
        if (!IsConnected) throw new Exception($"Failed to connect to robot {Name} at {Hostname}");
        _refreshStopwatch2.Start();
        var result = core.DataTable2.Refresh();
        _refreshStopwatch2.Stop();
        if (!result) throw new Exception($"Failed to refresh to robot {Name} at {Hostname}");
        _reader.UpdateSecondTableVariables();
        RefreshSecondTableTime=_refreshStopwatch2.Elapsed.TotalMilliseconds;
        _refreshStopwatch2.Reset();
    }
}